home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ABUSESRC.ZIP / AbuseSrc / macabuse / imlib / pcxread.c < prev    next >
C/C++ Source or Header  |  1997-05-20  |  5KB  |  219 lines

  1. #include "pcxread.hpp"
  2. #include "specs.hpp"
  3.  
  4. struct PCX_header_type
  5. {
  6.   char manufactururer,version,encoding,bits_per_pixel;
  7.   short xmin,ymin,xmax,ymax,hres,vres;
  8.   char palette[48];
  9.   char reserved,color_planes;
  10.   short bytes_per_line,palette_type;
  11.   char filter[58];
  12. } PCX_header;
  13.  
  14. int read_PCX_header(FILE *fp)
  15. {
  16.   if (!fread(&PCX_header.manufactururer,1,1,fp)) return 0;  
  17.   if (!fread(&PCX_header.version,1,1,fp)) return 0;  
  18.   if (!fread(&PCX_header.encoding,1,1,fp)) return 0;  
  19.   if (!fread(&PCX_header.bits_per_pixel,1,1,fp)) return 0;  
  20.   PCX_header.xmin=read_short(fp);
  21.   PCX_header.ymin=read_short(fp);  
  22.   PCX_header.xmax=read_short(fp);
  23.   PCX_header.ymax=read_short(fp);
  24.   PCX_header.hres=read_short(fp);
  25.   PCX_header.vres=read_short(fp);
  26.   if (!fread(PCX_header.palette,1,48,fp)) return 0;
  27.   if (!fread(&PCX_header.reserved,1,1,fp)) return 0;
  28.   if (!fread(&PCX_header.color_planes,1,1,fp)) return 0;
  29.   PCX_header.bytes_per_line=read_short(fp); 
  30.   PCX_header.palette_type=read_short(fp); 
  31.   if (!fread(PCX_header.filter,1,58,fp)) return 0;
  32.   return 1;
  33. }
  34.  
  35. int write_PCX_header(FILE *fp)
  36. {
  37.   if (!fwrite(&PCX_header.manufactururer,1,1,fp)) return 0;  
  38.   if (!fwrite(&PCX_header.version,1,1,fp)) return 0;  
  39.   if (!fwrite(&PCX_header.encoding,1,1,fp)) return 0;  
  40.   if (!fwrite(&PCX_header.bits_per_pixel,1,1,fp)) return 0;  
  41.   write_short(fp,PCX_header.xmin);
  42.   write_short(fp,PCX_header.ymin);  
  43.   write_short(fp,PCX_header.xmax);
  44.   write_short(fp,PCX_header.ymax);
  45.   write_short(fp,PCX_header.hres);
  46.   write_short(fp,PCX_header.vres);
  47.   if (!fwrite(PCX_header.palette,1,48,fp)) return 0;
  48.   if (!fwrite(&PCX_header.reserved,1,1,fp)) return 0;
  49.   if (!fwrite(&PCX_header.color_planes,1,1,fp)) return 0;
  50.   write_short(fp,PCX_header.bytes_per_line); 
  51.   write_short(fp,PCX_header.palette_type); 
  52.   if (!fwrite(PCX_header.filter,1,58,fp)) return 0;
  53.   return 1;
  54. }
  55.  
  56.  
  57.  
  58. PCX_type PCX_file_type(char *filename)
  59. {
  60.   FILE *fp=fopen(filename,"rb");  
  61.   if (!fp)
  62.   { set_error(imREAD_ERROR);  
  63.     return not_PCX;
  64.   }
  65.   
  66.   if (!read_PCX_header(fp))     
  67.   {
  68.     fclose(fp);    
  69.     set_error(imREAD_ERROR);  
  70.     return not_PCX;    
  71.   }
  72.   fclose(fp);      
  73.   if (PCX_header.manufactururer!=10) 
  74.     return not_PCX;  
  75.   if (PCX_header.color_planes==3 && PCX_header.bits_per_pixel==8)
  76.     return PCX_24;
  77.   else if (PCX_header.color_planes==1 && PCX_header.bits_per_pixel==8)
  78.     return PCX_8;
  79.   else return not_PCX;    
  80. }
  81.  
  82. void read_PCX_line(FILE *fp, unsigned char *start, short skip, int width)
  83. {
  84.   int c,n=0,i;
  85.   
  86.   do
  87.   {
  88.     c=fgetc(fp)&0xff;
  89.     if ((c&0xc0)==0xc0)
  90.     {
  91.       i=c&0x3f;
  92.       c=fgetc(fp);
  93.       while (i--) 
  94.       {
  95.     *start=c;
  96.     start+=skip;
  97.         n++;    
  98.       }
  99.     }
  100.     else
  101.     {
  102.       *start=c;
  103.       start+=skip;
  104.       n++;
  105.     }    
  106.   } while (n<width);    
  107. }
  108.  
  109.  
  110. image24 *read_PCX24(char *filename)
  111. {
  112.   if (PCX_file_type(filename)!=PCX_24) return NULL;  
  113.   FILE *fp=fopen(filename,"rb");
  114.   read_PCX_header(fp);  
  115.   image24 *im=new image24(PCX_header.xmax-PCX_header.xmin+1,
  116.               PCX_header.ymax-PCX_header.ymin+1);
  117.   int y;
  118.   for (y=0;y<im->height();y++)
  119.   {
  120.     read_PCX_line(fp,im->scan_line(y),3,PCX_header.bytes_per_line);
  121.     read_PCX_line(fp,im->scan_line(y)+1,3,PCX_header.bytes_per_line);
  122.     read_PCX_line(fp,im->scan_line(y)+2,3,PCX_header.bytes_per_line);    
  123.   }
  124.   fclose(fp);
  125.   return im;  
  126. }
  127.  
  128. image *read_PCX(char *filename, palette *&pal)
  129. {
  130.   if (PCX_file_type(filename)!=PCX_8) return NULL;  
  131.   FILE *fp=fopen(filename,"rb");
  132.   read_PCX_header(fp);
  133.   
  134.   image *im=new image(PCX_header.xmax-PCX_header.xmin+1,
  135.               PCX_header.ymax-PCX_header.ymin+1);
  136.   int y;
  137.   for (y=0;y<im->height();y++)
  138.     read_PCX_line(fp,im->scan_line(y),1,PCX_header.bytes_per_line);
  139.   unsigned char palette_confirm;  
  140.   if (!fread(&palette_confirm,1,1,fp) || palette_confirm!=12)
  141.   {    
  142.     pal=new palette;
  143.     pal->defaults();
  144.   }
  145.   else
  146.   {
  147.     pal=new palette;
  148.     fread(pal->addr(),1,256*3,fp);
  149.   } 
  150.   fclose(fp);
  151.   return im;  
  152. }  
  153.  
  154. void write_PCX(image *im, palette *pal, char *filename)
  155. {
  156.   FILE *fp=fopen(filename,"wb");
  157.   if (!fp) 
  158.   {
  159.     set_error(imWRITE_ERROR);
  160.     return ;
  161.   }
  162.   
  163.   
  164.   PCX_header.manufactururer=10;  
  165.   PCX_header.version=5;  
  166.   PCX_header.encoding=1;
  167.   PCX_header.bits_per_pixel=8;
  168.   PCX_header.xmin=0;
  169.   PCX_header.ymin=0;
  170.   PCX_header.xmax=im->width()-1;
  171.   PCX_header.ymax=im->height()-1;
  172.   PCX_header.hres=320;
  173.   PCX_header.vres=200;
  174.   PCX_header.reserved=0;
  175.   PCX_header.color_planes=1;
  176.   PCX_header.bytes_per_line=im->width();
  177.   PCX_header.palette_type=0;
  178.   memset(PCX_header.filter,0,58);
  179.  
  180.  
  181.   if (!write_PCX_header(fp)) 
  182.   {
  183.     set_error( imWRITE_ERROR);
  184.     return ;  
  185.   }
  186.   
  187.   int y,run_length,x;
  188.   unsigned char *sl,code;  
  189.   for (y=0;y<im->height();y++)
  190.   {
  191.     sl=im->scan_line(y);
  192.     for (x=0;x<im->width();)
  193.     {
  194.       run_length=1;      
  195.       while (x+run_length<im->width() && sl[x]==sl[x+run_length])
  196.         run_length++;
  197.       if (run_length==1 && sl[x]<64) 
  198.         fputc(sl[x],fp);      
  199.       else
  200.       {
  201.         if (run_length>=64)
  202.       run_length=63;
  203.     code=0xc0 | run_length;
  204.     fputc(code,fp);
  205.     fputc(sl[x],fp);
  206.     
  207.       }      
  208.       x+=run_length;
  209.       
  210.     }    
  211.   }
  212.   fputc(12,fp);  // note that there is a palette attached
  213.   fwrite(pal->addr(),1,256*3,fp);
  214.   fclose(fp);    
  215. }
  216.  
  217.  
  218.  
  219.